﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Security;
using CrmContacto.Contracts.Contracts;
using System.Configuration;
using System.Web.UI.HtmlControls;
using Web.Framework.Translate;
using Web.Framework.Svc;
using CrmContacto.Contracts.Contracts.Search;
using Web.Framework;

namespace Web.PuntoDeVenta.Code
{
    public abstract class BasePage : System.Web.UI.Page
    {
        protected BaseMasterPage masterPage { get; set; }        

        protected override void OnPreInit(EventArgs e)
        {
            base.OnPreInit(e);            
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            if (Context.Session != null)
            {
                //Tested and the IsNewSession is more advanced then simply checking if 
                // a cookie is present, it does take into account a session timeout, because 
                // I tested a timeout and it did show as a new session
                if (Session.IsNewSession)
                {
                    // If it says it is a new session, but an existing cookie exists, then it must 
                    // have timed out (can't use the cookie collection because even on first 
                    // request it already contains the cookie (request and response
                    // seem to share the collection)
                    string szCookieHeader = Request.Headers["Cookie"];
                    if ((null != szCookieHeader) && (szCookieHeader.IndexOf("ASP.NET_SessionId") >= 0))
                    {
                        //Session.Abandon();
                        FormsAuthentication.SignOut();
                        Response.Redirect("/Account/Login.aspx");
                    }
                }
            }
        }

        private static List<CompanyConfigurationKeyValue> companyConfigurationListKeyValue;
        public static List<CompanyConfigurationKeyValue> GetCompanyConfigurationKeyValue(Page page, int companyId)
        {
            if (companyConfigurationListKeyValue == null)
            {
                if (page.Cache["companyConfigurationListKeyValue"] == null)
                {
                    companyConfigurationListKeyValue = new List<CompanyConfigurationKeyValue>();
                    foreach (var d in WebServiceHelper.GetCompanyConfigurationKeyValues(companyId))
                    {
                        CompanyConfigurationKeyValue c = new CompanyConfigurationKeyValue();
                        c.CompanyId = companyId;
                        c.Key = d.Key;
                        c.Value = d.Value;
                        companyConfigurationListKeyValue.Add(c);
                    }

                    page.Cache["companyConfigurationListKeyValue"] = companyConfigurationListKeyValue;
                }
                else
                {
                    companyConfigurationListKeyValue = (List<CompanyConfigurationKeyValue>)page.Cache["companyConfigurationListKeyValue"];
                }
            }

            return companyConfigurationListKeyValue;
        }

        private static List<CompanyConfiguration> companyConfigurationList;
        public static List<CompanyConfiguration> GetCompanyConfigurationList(Page page)
        {           
                if (companyConfigurationList == null)
                {
                    if (page.Cache["companyConfigurationList"] == null)
                    {
                        companyConfigurationList = WebServiceHelper.GetCompanyConfigurations();
                        page.Cache["companyConfigurationList"] = companyConfigurationList;
                    }
                    else
                    {
                        companyConfigurationList = (List<CompanyConfiguration>)page.Cache["companyConfigurationList"];
                    }
                }

                return companyConfigurationList;            
        }

        protected override void OnPreLoad(EventArgs e)
        {
            masterPage = (BaseMasterPage)this.Master;           
            
            masterPage.PreLoad(new List<string>());

            base.OnPreLoad(e);

            LoadLocalization();
        }

        private void LoadLocalization()
        {
            string lenguajePorDefecto = ConfigurationManager.AppSettings["LenguajePorDefecto"];
            if (String.IsNullOrEmpty(lenguajePorDefecto))
            {
                throw new Exception("Debe configurar el lenguaje por defecto");
            }

            HtmlGenericControl js = new HtmlGenericControl("script");
            js.Attributes.Add("type", "text/javascript");
            js.Attributes.Add("src", string.Format("/Scripts/Localization/Localization.{0}.js", lenguajePorDefecto));
            this.Page.Header.Controls.Add(js);
        }        

        protected override void OnPreRender(EventArgs e)
        {
            // Aplica seguridad a los botones
            ApplySecurity();
            base.OnPreRender(e);
        }

        /// <summary>
        /// Aplica la seguridad en los botones a la pantalla
        /// </summary>
        protected virtual void ApplySecurity()
        {
        }

        /// <summary>
        /// Testea si el usuario tiene permisos para la operación
        /// </summary>
        /// <param name="operation"></param>
        /// <returns></returns>
        public bool HasPermissionFor(string operation)
        {
            return masterPage.HasPermissionFor(operation);
        }

        protected void HasPermissionToSeeMe(string operation)
        {
            if (!BaseMasterPage.IsAdmin && !HasPermissionFor(operation))
            {
                this.RedirectDefault(LocalizationProvider.Instance["SinPermisosParaRealizarOperacion"] + operation);
            }
        }

        public void RedirectDefault()
        {
            // TODO: chequear la session
            RedirectDefault(string.Empty);
        }

        public void RedirectDefault(string message)
        {
            // TODO: chequear la session
            Response.Redirect(string.Format("/App/Default.aspx?message={0}", message), true);
        }

        public static List<CrmContacto.Contracts.Contracts.PuntoDeVenta> GetPuntosDeVentaDto(int companyId)
        {
            List<CrmContacto.Contracts.Contracts.PuntoDeVenta> puntosDeVentaList = HttpContext.Current.Cache["GetPuntosDeVenta" + companyId.ToString()] as List<CrmContacto.Contracts.Contracts.PuntoDeVenta>;
            if (puntosDeVentaList == null)
            {
                puntosDeVentaList = WebServiceHelper.GetPuntoDeVentaDto(new ServiceOptions(), new PuntoDeVentaSearch() { EmpresaId = companyId });
                HttpContext.Current.Cache["GetPuntosDeVenta" + companyId.ToString()] = puntosDeVentaList;
            }

            return puntosDeVentaList;
        }

        protected static CrmContacto.Contracts.Contracts.PuntoDeVenta PuntoDeVentaCurrentSession
        {
            get
            {
                return HttpContext.Current.Session["PuntoDeVentaCurrentSession"] as CrmContacto.Contracts.Contracts.PuntoDeVenta;
            }
            set
            {
                HttpContext.Current.Session["PuntoDeVentaCurrentSession"] = value;
            }
        }

        /// <summary>
        /// Obtiene el punto de venta actual para el punto de venta seleccionado en el login
        /// </summary>
        /// <returns></returns>
        /// <remarks>No usar este método en el login</remarks>
        public static CrmContacto.Contracts.Contracts.PuntoDeVenta GetPuntoDeVentaCurrent(int? companyId = null, bool redirect = true)
        {
            CrmContacto.Contracts.Contracts.PuntoDeVenta ptoVta = null;
            if (PuntoDeVentaCurrentSession == null)
            {                 
                List<string> cookiePtoVta = HttpHelper.GetCookieValues(HttpHelper.cookiePtoVtaName, HttpContext.Current.Request);
                if (cookiePtoVta.Count > 1)
                {
                    int ptoVtaId = 0;
                    //this.lblPtoVtaInfo.Text = cookiePtoVta[1]; // + string.Format(" ({0})", cookiePtoVta[0]);
                    ptoVtaId = Convert.ToInt32(cookiePtoVta[0]);

                    if (!companyId.HasValue)
                    {
                        companyId = BaseWebPage.CompanyId;
                    }

                    var ptoVtaList = GetPuntosDeVentaDto(companyId.Value);
                    ptoVta = ptoVtaList.Where(p => p.Id == ptoVtaId).SingleOrDefault(); // TODO: Mejorar con un dictionary
                    if (ptoVta == null)
                    {
                        if (redirect)
                        {
                            FormsAuthentication.RedirectToLoginPage();
                        }
                    }
                    else
                    {
                        PuntoDeVentaCurrentSession = ptoVta;
                    }
                }
                else
                {
                    FormsAuthentication.RedirectToLoginPage();
                }
            }
            else
            {
                ptoVta = PuntoDeVentaCurrentSession;
            }

            return ptoVta;
        }        
    }
}